package com.lifeverse.service;

import com.lifeverse.entity.AuditLog;
import com.lifeverse.entity.enums.AuditAction;
import com.lifeverse.entity.enums.AuditResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统行为追踪服务
 * 分析系统行为模式，检测异常行为，生成行为报告
 */
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional(readOnly = true)
public class SystemBehaviorTracker {
    
    private final AuditLogService auditLogService;
    
    /**
     * 行为模式分析结果
     */
    public static class BehaviorPattern {
        private String patternType;
        private String description;
        private Double frequency;
        private Double riskScore;
        private LocalDateTime firstOccurrence;
        private LocalDateTime lastOccurrence;
        private Long occurrenceCount;
        private Map<String, Object> metadata;
        
        // 构造函数和getter/setter
        public BehaviorPattern(String patternType, String description) {
            this.patternType = patternType;
            this.description = description;
            this.metadata = new HashMap<>();
        }
        
        // Getters and Setters
        public String getPatternType() { return patternType; }
        public void setPatternType(String patternType) { this.patternType = patternType; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public Double getFrequency() { return frequency; }
        public void setFrequency(Double frequency) { this.frequency = frequency; }
        
        public Double getRiskScore() { return riskScore; }
        public void setRiskScore(Double riskScore) { this.riskScore = riskScore; }
        
        public LocalDateTime getFirstOccurrence() { return firstOccurrence; }
        public void setFirstOccurrence(LocalDateTime firstOccurrence) { this.firstOccurrence = firstOccurrence; }
        
        public LocalDateTime getLastOccurrence() { return lastOccurrence; }
        public void setLastOccurrence(LocalDateTime lastOccurrence) { this.lastOccurrence = lastOccurrence; }
        
        public Long getOccurrenceCount() { return occurrenceCount; }
        public void setOccurrenceCount(Long occurrenceCount) { this.occurrenceCount = occurrenceCount; }
        
        public Map<String, Object> getMetadata() { return metadata; }
        public void setMetadata(Map<String, Object> metadata) { this.metadata = metadata; }
    }
    
    /**
     * 异常行为检测结果
     */
    public static class AnomalyDetectionResult {
        private String anomalyType;
        private String description;
        private Double severity;
        private LocalDateTime detectedAt;
        private List<AuditLog> relatedLogs;
        private Map<String, Object> evidence;
        
        public AnomalyDetectionResult(String anomalyType, String description, Double severity) {
            this.anomalyType = anomalyType;
            this.description = description;
            this.severity = severity;
            this.detectedAt = LocalDateTime.now();
            this.relatedLogs = new ArrayList<>();
            this.evidence = new HashMap<>();
        }
        
        // Getters and Setters
        public String getAnomalyType() { return anomalyType; }
        public void setAnomalyType(String anomalyType) { this.anomalyType = anomalyType; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public Double getSeverity() { return severity; }
        public void setSeverity(Double severity) { this.severity = severity; }
        
        public LocalDateTime getDetectedAt() { return detectedAt; }
        public void setDetectedAt(LocalDateTime detectedAt) { this.detectedAt = detectedAt; }
        
        public List<AuditLog> getRelatedLogs() { return relatedLogs; }
        public void setRelatedLogs(List<AuditLog> relatedLogs) { this.relatedLogs = relatedLogs; }
        
        public Map<String, Object> getEvidence() { return evidence; }
        public void setEvidence(Map<String, Object> evidence) { this.evidence = evidence; }
    }
    
    /**
     * 分析用户行为模式
     */
    public List<BehaviorPattern> analyzeUserBehaviorPatterns(String userId, LocalDateTime startTime, LocalDateTime endTime) {
        List<BehaviorPattern> patterns = new ArrayList<>();
        
        try {
            // 获取用户的审计日志
            List<AuditLog> userLogs = getUserAuditLogs(userId, startTime, endTime);
            
            if (userLogs.isEmpty()) {
                return patterns;
            }
            
            // 分析登录模式
            patterns.add(analyzeLoginPattern(userLogs));
            
            // 分析操作频率模式
            patterns.add(analyzeOperationFrequencyPattern(userLogs));
            
            // 分析时间模式
            patterns.add(analyzeTimePattern(userLogs));
            
            // 分析失败模式
            patterns.add(analyzeFailurePattern(userLogs));
            
            // 分析资源访问模式
            patterns.add(analyzeResourceAccessPattern(userLogs));
            
        } catch (Exception e) {
            log.error("分析用户行为模式失败: userId={}", userId, e);
        }
        
        return patterns.stream().filter(Objects::nonNull).collect(Collectors.toList());
    }
    
    /**
     * 检测异常行为
     */
    public List<AnomalyDetectionResult> detectAnomalies(LocalDateTime startTime, LocalDateTime endTime) {
        List<AnomalyDetectionResult> anomalies = new ArrayList<>();
        
        try {
            // 检测暴力破解攻击
            anomalies.addAll(detectBruteForceAttacks(startTime, endTime));
            
            // 检测异常IP访问
            anomalies.addAll(detectSuspiciousIpActivity(startTime, endTime));
            
            // 检测权限提升尝试
            anomalies.addAll(detectPrivilegeEscalationAttempts(startTime, endTime));
            
            // 检测异常操作频率
            anomalies.addAll(detectAbnormalOperationFrequency(startTime, endTime));
            
            // 检测异常时间访问
            anomalies.addAll(detectOffHoursActivity(startTime, endTime));
            
            // 检测数据泄露风险
            anomalies.addAll(detectDataExfiltrationRisk(startTime, endTime));
            
        } catch (Exception e) {
            log.error("检测异常行为失败", e);
        }
        
        return anomalies;
    }
    
    /**
     * 生成行为分析报告
     */
    public Map<String, Object> generateBehaviorReport(LocalDateTime startTime, LocalDateTime endTime) {
        Map<String, Object> report = new HashMap<>();
        
        try {
            // 基础统计
            report.put("totalOperations", getTotalOperations(startTime, endTime));
            report.put("uniqueUsers", getUniqueUsers(startTime, endTime));
            report.put("failureRate", getFailureRate(startTime, endTime));
            
            // 操作统计
            report.put("actionStatistics", auditLogService.getActionStatistics(startTime, endTime));
            report.put("resultStatistics", auditLogService.getResultStatistics(startTime, endTime));
            
            // 异常检测结果
            List<AnomalyDetectionResult> anomalies = detectAnomalies(startTime, endTime);
            report.put("anomalies", anomalies);
            report.put("anomalyCount", anomalies.size());
            report.put("highSeverityAnomalies", anomalies.stream()
                    .filter(a -> a.getSeverity() >= 0.8)
                    .count());
            
            // 可疑IP统计
            List<Object[]> suspiciousIps = auditLogService.findSuspiciousIpAddresses(startTime, endTime, 100L);
            report.put("suspiciousIpAddresses", suspiciousIps);
            
            // 风险评估
            report.put("overallRiskScore", calculateOverallRiskScore(anomalies));
            
            // 报告生成时间
            report.put("generatedAt", LocalDateTime.now());
            report.put("reportPeriod", Map.of("startTime", startTime, "endTime", endTime));
            
        } catch (Exception e) {
            log.error("生成行为分析报告失败", e);
            report.put("error", "报告生成失败: " + e.getMessage());
        }
        
        return report;
    }
    
    /**
     * 获取用户审计日志
     */
    private List<AuditLog> getUserAuditLogs(String userId, LocalDateTime startTime, LocalDateTime endTime) {
        // 这里简化实现，实际应该分页获取
        return auditLogService.findByMultipleConditions(userId, null, null, null, 
                startTime, endTime, null, org.springframework.data.domain.Pageable.unpaged())
                .getContent();
    }
    
    /**
     * 分析登录模式
     */
    private BehaviorPattern analyzeLoginPattern(List<AuditLog> logs) {
        List<AuditLog> loginLogs = logs.stream()
                .filter(log -> log.getAction().isAuthenticationAction())
                .collect(Collectors.toList());
        
        if (loginLogs.isEmpty()) {
            return null;
        }
        
        BehaviorPattern pattern = new BehaviorPattern("LOGIN_PATTERN", "用户登录行为模式");
        pattern.setOccurrenceCount((long) loginLogs.size());
        pattern.setFirstOccurrence(loginLogs.get(loginLogs.size() - 1).getTimestamp());
        pattern.setLastOccurrence(loginLogs.get(0).getTimestamp());
        
        // 计算登录成功率
        long successfulLogins = loginLogs.stream()
                .filter(log -> log.getAction() == AuditAction.LOGIN)
                .count();
        long failedLogins = loginLogs.stream()
                .filter(log -> log.getAction() == AuditAction.LOGIN_FAILED)
                .count();
        
        double successRate = failedLogins > 0 ? (double) successfulLogins / (successfulLogins + failedLogins) : 1.0;
        pattern.setFrequency(successRate);
        pattern.setRiskScore(1.0 - successRate); // 失败率越高风险越大
        
        pattern.getMetadata().put("successfulLogins", successfulLogins);
        pattern.getMetadata().put("failedLogins", failedLogins);
        pattern.getMetadata().put("successRate", successRate);
        
        return pattern;
    }
    
    /**
     * 分析操作频率模式
     */
    private BehaviorPattern analyzeOperationFrequencyPattern(List<AuditLog> logs) {
        BehaviorPattern pattern = new BehaviorPattern("OPERATION_FREQUENCY", "操作频率模式");
        
        // 按小时统计操作次数
        Map<Integer, Long> hourlyOperations = logs.stream()
                .collect(Collectors.groupingBy(
                        log -> log.getTimestamp().getHour(),
                        Collectors.counting()
                ));
        
        // 计算平均操作频率
        double avgOperationsPerHour = hourlyOperations.values().stream()
                .mapToLong(Long::longValue)
                .average()
                .orElse(0.0);
        
        pattern.setFrequency(avgOperationsPerHour);
        pattern.setOccurrenceCount((long) logs.size());
        
        // 检测异常高频操作
        long maxOperationsInHour = hourlyOperations.values().stream()
                .mapToLong(Long::longValue)
                .max()
                .orElse(0L);
        
        double riskScore = maxOperationsInHour > avgOperationsPerHour * 3 ? 0.8 : 0.2;
        pattern.setRiskScore(riskScore);
        
        pattern.getMetadata().put("hourlyOperations", hourlyOperations);
        pattern.getMetadata().put("avgOperationsPerHour", avgOperationsPerHour);
        pattern.getMetadata().put("maxOperationsInHour", maxOperationsInHour);
        
        return pattern;
    }
    
    /**
     * 分析时间模式
     */
    private BehaviorPattern analyzeTimePattern(List<AuditLog> logs) {
        BehaviorPattern pattern = new BehaviorPattern("TIME_PATTERN", "时间访问模式");
        
        // 统计工作时间外的操作
        long offHoursOperations = logs.stream()
                .filter(log -> {
                    int hour = log.getTimestamp().getHour();
                    return hour < 8 || hour > 18; // 假设工作时间是8-18点
                })
                .count();
        
        double offHoursRatio = (double) offHoursOperations / logs.size();
        pattern.setFrequency(1.0 - offHoursRatio); // 工作时间内操作的比例
        pattern.setRiskScore(offHoursRatio); // 工作时间外操作比例越高风险越大
        
        pattern.getMetadata().put("offHoursOperations", offHoursOperations);
        pattern.getMetadata().put("totalOperations", logs.size());
        pattern.getMetadata().put("offHoursRatio", offHoursRatio);
        
        return pattern;
    }
    
    /**
     * 分析失败模式
     */
    private BehaviorPattern analyzeFailurePattern(List<AuditLog> logs) {
        BehaviorPattern pattern = new BehaviorPattern("FAILURE_PATTERN", "操作失败模式");
        
        long failedOperations = logs.stream()
                .filter(log -> log.getResult().isFailure())
                .count();
        
        double failureRate = (double) failedOperations / logs.size();
        pattern.setFrequency(1.0 - failureRate); // 成功率
        pattern.setRiskScore(failureRate); // 失败率越高风险越大
        
        pattern.getMetadata().put("failedOperations", failedOperations);
        pattern.getMetadata().put("totalOperations", logs.size());
        pattern.getMetadata().put("failureRate", failureRate);
        
        return pattern;
    }
    
    /**
     * 分析资源访问模式
     */
    private BehaviorPattern analyzeResourceAccessPattern(List<AuditLog> logs) {
        BehaviorPattern pattern = new BehaviorPattern("RESOURCE_ACCESS", "资源访问模式");
        
        // 统计访问的资源类型
        Map<String, Long> resourceTypeAccess = logs.stream()
                .filter(log -> log.getResourceType() != null)
                .collect(Collectors.groupingBy(
                        AuditLog::getResourceType,
                        Collectors.counting()
                ));
        
        // 计算资源访问多样性
        double diversity = resourceTypeAccess.size();
        pattern.setFrequency(diversity);
        
        // 检测是否有异常的资源访问
        boolean hasAbnormalAccess = resourceTypeAccess.values().stream()
                .anyMatch(count -> count > logs.size() * 0.8); // 如果某种资源访问超过80%可能异常
        
        pattern.setRiskScore(hasAbnormalAccess ? 0.7 : 0.2);
        pattern.getMetadata().put("resourceTypeAccess", resourceTypeAccess);
        pattern.getMetadata().put("resourceTypeDiversity", diversity);
        
        return pattern;
    }
    
    /**
     * 检测暴力破解攻击
     */
    private List<AnomalyDetectionResult> detectBruteForceAttacks(LocalDateTime startTime, LocalDateTime endTime) {
        List<AnomalyDetectionResult> anomalies = new ArrayList<>();
        
        // 查找登录失败的日志
        List<Object[]> suspiciousIps = auditLogService.findSuspiciousIpAddresses(startTime, endTime, 10L);
        
        for (Object[] ipData : suspiciousIps) {
            String ipAddress = (String) ipData[0];
            Long operationCount = (Long) ipData[1];
            
            if (operationCount > 50) { // 阈值可配置
                AnomalyDetectionResult anomaly = new AnomalyDetectionResult(
                        "BRUTE_FORCE_ATTACK",
                        "检测到来自IP " + ipAddress + " 的可能暴力破解攻击",
                        Math.min(1.0, operationCount / 100.0)
                );
                
                anomaly.getEvidence().put("ipAddress", ipAddress);
                anomaly.getEvidence().put("operationCount", operationCount);
                anomaly.getEvidence().put("threshold", 50);
                
                anomalies.add(anomaly);
            }
        }
        
        return anomalies;
    }
    
    /**
     * 检测可疑IP活动
     */
    private List<AnomalyDetectionResult> detectSuspiciousIpActivity(LocalDateTime startTime, LocalDateTime endTime) {
        // 实现可疑IP检测逻辑
        return new ArrayList<>();
    }
    
    /**
     * 检测权限提升尝试
     */
    private List<AnomalyDetectionResult> detectPrivilegeEscalationAttempts(LocalDateTime startTime, LocalDateTime endTime) {
        // 实现权限提升检测逻辑
        return new ArrayList<>();
    }
    
    /**
     * 检测异常操作频率
     */
    private List<AnomalyDetectionResult> detectAbnormalOperationFrequency(LocalDateTime startTime, LocalDateTime endTime) {
        // 实现异常操作频率检测逻辑
        return new ArrayList<>();
    }
    
    /**
     * 检测非工作时间活动
     */
    private List<AnomalyDetectionResult> detectOffHoursActivity(LocalDateTime startTime, LocalDateTime endTime) {
        // 实现非工作时间活动检测逻辑
        return new ArrayList<>();
    }
    
    /**
     * 检测数据泄露风险
     */
    private List<AnomalyDetectionResult> detectDataExfiltrationRisk(LocalDateTime startTime, LocalDateTime endTime) {
        // 实现数据泄露风险检测逻辑
        return new ArrayList<>();
    }
    
    /**
     * 获取总操作数
     */
    private Long getTotalOperations(LocalDateTime startTime, LocalDateTime endTime) {
        return auditLogService.findByTimeRange(startTime, endTime, 
                org.springframework.data.domain.Pageable.unpaged()).getTotalElements();
    }
    
    /**
     * 获取唯一用户数
     */
    private Long getUniqueUsers(LocalDateTime startTime, LocalDateTime endTime) {
        // 简化实现，实际应该查询数据库
        return 0L;
    }
    
    /**
     * 获取失败率
     */
    private Double getFailureRate(LocalDateTime startTime, LocalDateTime endTime) {
        List<Object[]> resultStats = auditLogService.getResultStatistics(startTime, endTime);
        
        long totalOperations = resultStats.stream()
                .mapToLong(stat -> (Long) stat[1])
                .sum();
        
        long failedOperations = resultStats.stream()
                .filter(stat -> {
                    AuditResult result = (AuditResult) stat[0];
                    return result.isFailure();
                })
                .mapToLong(stat -> (Long) stat[1])
                .sum();
        
        return totalOperations > 0 ? (double) failedOperations / totalOperations : 0.0;
    }
    
    /**
     * 计算整体风险评分
     */
    private Double calculateOverallRiskScore(List<AnomalyDetectionResult> anomalies) {
        if (anomalies.isEmpty()) {
            return 0.0;
        }
        
        return anomalies.stream()
                .mapToDouble(AnomalyDetectionResult::getSeverity)
                .average()
                .orElse(0.0);
    }
}